/**
 * 生成 where 条件代码，实体动态查询
 * @param table {Table}
 * @returns {string}
 */
const where = table => {
  const {
    columns,
    adapters
  } = table
  const adapter = adapters.map(o => o.where).reduce((s, v) => Object.assign(s, v), {})
  return columns
    .map(column => {
      const {
        name,
        dataType,
        length
      } = column
      if (adapter[name]) {
        return adapter[name](column)
      }
      switch (dataType.mysql) {
        case 'CHAR':
          return `//                .and(${name}, () -> ${name}.endsWith("%") || ${name}.startsWith("%") ? table.${name}.like(${name}) : table.${name}.eq(${name}))`
        case 'VARCHAR':
          return length < 100
            ? `//                .and(${name}, () -> ${name}.endsWith("%") || ${name}.startsWith("%") ? table.${name}.like(${name}) : table.${name}.eq(${name}))`
            : `//                .and(${name}, () -> ${name}.endsWith("%") || ${name}.startsWith("%") ? table.${name}.like(${name}) : table.${name}.startsWith(${name}))`
        case 'TEXT':
        case 'MEDIUMTEXT':
        case 'LONGTEXT':
          return `//                .and(${name}, () -> ${name}.endsWith("%") || ${name}.startsWith("%") ? table.${name}.like(${name}) : table.${name}.contains(${name}))`
        case 'DECIMAL':
        case 'DOUBLE':
        case 'FLOAT':
          return `//                .and(${name}Range, () -> table.${name}.between(${name}Range.getMin(), ${name}Range.getMax()))`
        case 'DATE':
        case 'DATETIME':
        case 'TIMESTAMP':
          return `//                .and(${name}Range, () -> table.${name}.between(${name}Range.rebuild().getBegin(), ${name}Range.getEnd()))`
        case 'JSON':
          return `//                .and(${name}, () -> Expressions.booleanTemplate("JSON_CONTAINS({0},{1})>0", table.${name}, JSON.toJSONString(${name})))`
      }
      return `//                .and(${name}, () -> table.${name}.eq(${name}))`
    })
    .filter(Boolean).join('\n')
}
export default where
